package com.apobates.jforum2.troll.nest.service;

import com.apobates.jforum2.troll.forum.stub.vo.BoardCaseGroupVo;
import com.apobates.jforum2.troll.forum.stub.vo.BoardCollectStatsVo;
import com.apobates.jforum2.troll.forum.stub.vo.BoardConfigVo;
import com.apobates.jforum2.troll.forum.stub.vo.BoardModelVo;
import com.apobates.jforum2.troll.forum.stub.vo.BoardStatsCollectVo;
import com.apobates.jforum2.troll.forum.stub.vo.BoardStatsVo;
import com.apobates.jforum2.troll.forum.stub.vo.BoardVo;
import com.apobates.jforum2.troll.nest.FrontFeignClientConfig;
import com.apobates.jforum2.troll.nest.service.BoardClient.BoardFallbackFactory;
import java.util.Collections;
import java.util.List;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 版块服务客户端
 * @author xiaofanku
 * @since 20210413
 */
@FeignClient(value="TROLL-GATEWAY",
            contextId="boardClient",
            fallbackFactory=BoardFallbackFactory.class,
            configuration = FrontFeignClientConfig.class
)
@RequestMapping(value="/board")
public interface BoardClient {
    //1:版块列表底部的统计
    @GetMapping("/collect")
    ResponseEntity<BoardStatsCollectVo> getCollectStats(@RequestParam(value="cycle", required=false, defaultValue="30") int statsCycle);
    
    //2:指定的版块
    @GetMapping("/{id}")
    ResponseEntity<BoardVo> get(@PathVariable("id")long boardId);
    
    //3:指定版块的图标
    @GetMapping("/{id}/ico/{scale}")
    ResponseEntity<String> getIco(@PathVariable("id")long boardId, @PathVariable("scale")String scale);
    
    //4:指定版块组下的所有版块
    @GetMapping("/all/{volume}")
    List<BoardVo> getAllBoardsByVolume(@PathVariable("volume")int boardGroupId);
    
    //5:所有可用的版块
    @GetMapping("/all")
    List<BoardVo> getAll();
    
    //6:指定的版块[并加载版块的统计]
    @GetMapping("/{id}/cascade/stats")
    ResponseEntity<BoardCollectStatsVo> getBoardStatsById(@PathVariable("id")long boardId);
    
    //7:查看指定版块的统计
    @GetMapping("/{id}/stats")
    ResponseEntity<BoardStatsVo> getStats(@PathVariable("id")long boardId);
    
    //8:查看多个版块的统计并填充今日话题数
    @PostMapping(value="/stats/multi", consumes="application/x-www-form-urlencoded")
    List<BoardStatsVo> getMultiStats(@RequestParam("records")String boardIdString);
    
    //9:所有的版块统计记录
    @GetMapping("/stats/all")
    List<BoardStatsVo> getAllStats();
    
    //10:查看指定版块并及联加载版块组
    @GetMapping("/{id}/volume/{volume}")
    ResponseEntity<BoardCaseGroupVo> getBoardCascadeBoardGroup(@PathVariable("id")long boardId, @PathVariable("volume")int boardGroupId);
    
    //11:指定的会员是否收藏过版块
    @GetMapping("/{id}/favorite/member/{member}")
    boolean isFavoriteBoard(@PathVariable("id")long boardId, @PathVariable("member")long memberId);
    
    //12
    
    //13:查看指定版块并加载版块统计
    @GetMapping("/multi/stats")
    List<BoardCollectStatsVo> getMultiBoardAndStats(@RequestParam("boardIds") String boardIdString);
    
    //14:查看指定版块并解码图标
    @GetMapping("/multi/icon")
    List<BoardVo> getMultiBoardAndDecodeIco(@RequestParam("boardIds") String boardIdString,@RequestParam("scale")String scale);
    
    //15
    
    //22:查看指定的版块
    @GetMapping("/multi")
    List<BoardVo> getMultiBoard(@RequestParam("boardIds") String boardIdString);
    
    //16:收藏
    @PutMapping(value="/{id}/favorite", consumes="application/x-www-form-urlencoded")
    boolean favorite(
            @PathVariable("id")long boardId,
            @RequestParam("member")long memberId,
            @RequestParam("nickname") String memberNickname,
            @RequestParam("token") String token,
            @RequestParam("ip")String ipAddr);
    
    //17:取消收藏
    @PutMapping(value="/{id}/favorite/cancel", consumes="application/x-www-form-urlencoded")
    boolean cancelFavorite(
            @PathVariable("id")long boardId,
            @RequestParam("member")long memberId,
            @RequestParam("nickname") String memberNickname,
            @RequestParam("token") String token,
            @RequestParam("ip")String ipAddr);
    
    //18:锁定
    @PutMapping(value="/{id}/lock", consumes="application/x-www-form-urlencoded")
    boolean locked(
            @PathVariable("id")long boardId,
            @RequestParam("volume")int boardGroupId,
            @RequestParam("member")long memberId,
            @RequestParam("nickname") String memberNickname,
            @RequestParam("token") String token,
            @RequestParam("ip")String ipAddr);
    
    //19:解锁
    @PutMapping(value="/{id}/lock/cancel", consumes="application/x-www-form-urlencoded")
    boolean cancelLock(
            @PathVariable("id")long boardId,
            @RequestParam("volume")int boardGroupId,
            @RequestParam("member")long memberId,
            @RequestParam("nickname") String memberNickname,
            @RequestParam("token") String token,
            @RequestParam("ip")String ipAddr);
    
    //20:查看指定版块的配置文件
    @GetMapping("/{id}/config")
    ResponseEntity<BoardConfigVo> getConfig(@PathVariable("id")long boardId);
    
    //21:版块Top榜
    @GetMapping("/model")
    List<BoardModelVo> getTopBoard();
    
    @Component
    static class BoardFallbackFactory implements FallbackFactory<BoardClientFallback> {
        @Override
        public BoardClientFallback create(Throwable cause) {
            return new BoardClientFallback();
        }
    }
    static class BoardClientFallback implements BoardClient{
        
        @Override
        public ResponseEntity<BoardVo> get(long boardId) {
            return ResponseEntity.notFound().build();
        }

        @Override
        public ResponseEntity<BoardStatsCollectVo> getCollectStats(int statsCycle) {
            return ResponseEntity.notFound().build();
        }

        @Override
        public ResponseEntity<String> getIco(long boardId, String scale) {
            return ResponseEntity.notFound().build();
        }

        @Override
        public List<BoardVo> getAll() {
            return Collections.emptyList();
        }

        @Override
        public ResponseEntity<BoardStatsVo> getStats(long boardId) {
            return ResponseEntity.notFound().build();
        }

        @Override
        public List<BoardStatsVo> getMultiStats(String boardIdString) {
            return Collections.emptyList();
        }

        @Override
        public List<BoardStatsVo> getAllStats() {
            return Collections.emptyList();
        }

        @Override
        public boolean isFavoriteBoard(long boardId, long memberId) {
            return false;
        }

        @Override
        public boolean favorite(long boardId, long memberId, String memberNickname, String token, String ipAddr) {
            return false;
        }

        @Override
        public boolean cancelFavorite(long boardId, long memberId, String memberNickname, String token, String ipAddr) {
            return false;
        }

        @Override
        public boolean locked(long boardId, int boardGroupId, long memberId, String memberNickname, String token, String ipAddr) {
            return false;
        }

        @Override
        public boolean cancelLock(long boardId, int boardGroupId, long memberId, String memberNickname, String token, String ipAddr) {
            return false;
        }

        @Override
        public ResponseEntity<BoardConfigVo> getConfig(long boardId) {
            return ResponseEntity.notFound().build();
        }

        @Override
        public List<BoardModelVo> getTopBoard() {
            return Collections.emptyList();
        }

        @Override
        public List<BoardVo> getAllBoardsByVolume(int boardGroupId) {
            return Collections.emptyList();
        }

        @Override
        public ResponseEntity<BoardCollectStatsVo> getBoardStatsById(long boardId) {
            return ResponseEntity.notFound().build();
        }

        @Override
        public ResponseEntity<BoardCaseGroupVo> getBoardCascadeBoardGroup(long boardId, int boardGroupId) {
            return ResponseEntity.notFound().build();
        }

        @Override
        public List<BoardCollectStatsVo> getMultiBoardAndStats(String boardIdString) {
            return Collections.emptyList();
        }

        @Override
        public List<BoardVo> getMultiBoard(String boardIdString) {
            return Collections.emptyList();
        }

        @Override
        public List<BoardVo> getMultiBoardAndDecodeIco(String boardIdString, String scale) {
            return Collections.emptyList();
        }
    
    }
}